#ifndef __CGRA_SIM_API_H__
#define __CGRA_SIM_API_H__

#include <cstdint>
#include <stdint.h>
#include <iostream>

template<typename T, int N>
struct RankedMemrefType {
  T *basePtr;
  T *data;
  int64_t offset;
  int64_t sizes[N];
  int64_t strides[N];
  void print(){
    for(int i = 0; i < this->sizes[0]; i++) {
      std::cout << data[i] << " ";
      if (i % 10 == 0 && i != 0) {
        std::cout << std::endl;
      }
    } 
  }
};


typedef enum ck_md_algo_
{
    CK_MD_SHA1 = 0,
    CK_MD_SHA256 = 1,
    CK_MD_SHA384 = 2,
    CK_MD_SM3 = 4,
    CK_MD_MD5 = 5,
    CK_MD_AES = 6
} ck_md_algo_e;

void hash_padding(int algo, unsigned char* in, uint32_t in_len, unsigned char* out, uint32_t* out_len);

void pkcs7_padding(unsigned char* in, uint32_t in_len, unsigned char* out, uint32_t* out_len);

extern "C" {
void _mlir_ciface_cgra_sha1_run(RankedMemrefType<uint8_t, 1>* input,
              RankedMemrefType<uint8_t, 1>* output, uint32_t plain_len);

void _mlir_ciface_cgra_md5_run(RankedMemrefType<uint8_t, 1>* input,
              RankedMemrefType<uint8_t, 1>* output, uint32_t plain_len);

void _mlir_ciface_cgra_sm3_run(RankedMemrefType<uint8_t, 1>* input,
              RankedMemrefType<uint8_t, 1>* output, uint32_t plain_len);

void _mlir_ciface_cgra_aes_run(RankedMemrefType<uint8_t, 1>* input,
              RankedMemrefType<uint8_t, 1>* output, uint32_t plain_len, RankedMemrefType<uint8_t, 1>* key);

int simulate(const char*, const char*, const char*);
}


#endif